package com.tao.utilslib.list;

import android.os.Build;

import com.tao.utilslib.data.Obj;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class ListUtil {
    /**
     * list 排序
     *
     * @param dataList
     * @param comparator
     * @param tempArray
     * @param <T>
     * @return
     */
    public static <T> List<T> sort(List<T> dataList, Comparator comparator, T[] tempArray) {
        if (Obj.isNULL(dataList)) return new ArrayList<>();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            dataList.sort(comparator);
            return dataList;
        }
        if (tempArray.length != dataList.size())
            return dataList;

        T[] dataBeans = dataList.toArray(tempArray);
        Arrays.sort(dataBeans, comparator);
        return new ArrayList<>(Arrays.asList(dataBeans));

    }

    /**
     * -
     * 递归2分查找
     *
     * @param dataList
     * @param resultCall
     * @param <T>
     * @return
     */
    public static <T> boolean serch(List<T> dataList, OnserchResult<T> resultCall) {
        if (Obj.isNULL(dataList)) return false;
        if (dataList.size() < 2) {
            T s = dataList.get(0);
            if (resultCall.match(s)) {
                resultCall.onResult(s);
                return true;
            }
            return false;
        }
        if (serch(dataList.subList(0, dataList.size() / 2), resultCall)) {
            return true;
        }
        return serch(dataList.subList(dataList.size() / 2, dataList.size()), resultCall);
    }

    /**
     * @param dataList
     * @param resultCall
     * @param <T>
     * @return
     */
    public static <T> boolean serch2(List<T> dataList, OnserchResult<T> resultCall) {
        if (Obj.isNULL(dataList)) return false;

        return serch2(dataList, resultCall, 0, 2);

    }

    public static <T> boolean serch2(List<T> dataList, OnserchResult<T> resultCall, int st, int n) {
        for (int i = st; i <= (n > dataList.size() ? dataList.size() : n); i++) {
            if (resultCall.match(dataList.get(i))) {
                return true;
            }
        }
        return serch2(dataList, resultCall, n, n * 2);
    }


    /**
     * 从指定位置开始查找 到末尾未查到 则从头开始查找
     * 应用于有序队列知道 元素处于大概位置
     *
     * @param dataList
     * @param n
     * @param resultCall
     * @param <T>
     * @return
     */
    public static <T> boolean forSerch(List<T> dataList, int n, OnserchResult<T> resultCall) {
        if (Obj.isNULL(dataList)) return false;

        if (forSerchSection(dataList, resultCall, n, dataList.size())) {
            return true;
        }
        return forSerchSection(dataList, resultCall, 0, n);
    }

    /**
     * 按区间查找
     *
     * @param dataList
     * @param resultCall
     * @param st
     * @param size
     * @param <T>
     * @return
     */
    private static <T> boolean forSerchSection(List<T> dataList, OnserchResult<T> resultCall, int st, int size) {
        if (Obj.isNULL(dataList)) return false;

        for (int i = st; i < size; i++) {
            T t = dataList.get(i);
            if (resultCall.match(t)) {
                resultCall.onResult(t);
                return true;
            }
        }
        return false;
    }

    /**
     * 普通for查找
     *
     * @param dataList
     * @param onserchResult
     * @param <T>
     * @return
     */
    public static <T> boolean forSerch(List<T> dataList, OnserchResult<T> onserchResult) {
        for (T str : dataList) {
            if (onserchResult.match(str)) {
                onserchResult.onResult(str);
                return true;
            }
        }
        return false;
    }

    /**
     * 搜索算法
     * 从列表中部开始向两边搜索
     *
     * @param dataList
     * @param resultCall
     * @param <T>
     * @return
     */
    public static <T> boolean serch3(List<T> dataList, OnserchResult<T> resultCall) {
        for (int i = 0; i < dataList.size() / 2; i++) {

            if (serchLeft(dataList, resultCall, i)) {
                return true;
            } else if (serchRight(dataList, resultCall, i)) {
                return true;
            }
        }
        return false;
    }

    private static <T> boolean serchRight(List<T> dataList, OnserchResult<T> resultCall, int i) {

        return false;
    }

    private static <T> boolean serchLeft(List<T> dataList, OnserchResult<T> resultCall, int i) {
        return false;
    }


    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        int size = 1000000;
        for (int i = 0; i < size; i++) {
            stringList.add("" + i);
        }
        long l = System.currentTimeMillis();


        long t1 = 0;
        long t2 = 0;
        for (int i = 0; i < 100; i++) {
            final int nextInt = new Random().nextInt(size);

            l = System.currentTimeMillis();
            boolean serch = serch2(stringList, new OnserchResult<String>() {
                @Override
                public boolean match(String s) {
                    return s.equals("" + nextInt);
                }

                @Override
                public void onResult(String result) {
                }
            });
            t1 += (System.currentTimeMillis() - l);
            l = System.currentTimeMillis();
            boolean forserch = forSerch(stringList, new OnserchResult<String>() {
                @Override
                public boolean match(String s) {
                    return s.equals("" + nextInt);
                }

                @Override
                public void onResult(String result) {

                }
            });

            t2 += (System.currentTimeMillis() - l);

        }


        System.err.println("1耗时：" + t1);
        System.err.println("2耗时：" + t2);


    }

    /**
     * 根据条件移除条目 单条
     *
     * @param entrustBeans
     * @param removeResult
     * @param <T>
     * @return
     */
    public static <T> boolean removeItem(List<T> entrustBeans, OnRemoveResult<T> removeResult) {
        for (int i = entrustBeans.size() - 1; i > -1; i--) {
            T s = entrustBeans.get(i);
            if (removeResult.match(s)) {
                entrustBeans.remove(s);
                removeResult.onRemove(s);
                return true;
            }
        }
        return false;
    }

    /**
     * 移除条目 多条
     *
     * @param entrustBeans
     * @param removeResult
     * @param <T>
     */
    public static <T> void removeItems(List<T> entrustBeans, OnRemoveResult<T> removeResult) {
        for (int i = entrustBeans.size() - 1; i > -1; i--) {
            T s = entrustBeans.get(i);
            if (removeResult.match(s)) {
                entrustBeans.remove(s);
                removeResult.onRemove(s);
            }
        }
    }

    /**
     * for 循环 默认正向
     *
     * @param beanList
     * @param onForItem
     * @param <T>
     */
    public static <T> void forEarch(List<T> beanList, OnForItem<T> onForItem) {
        forEarch(beanList, onForItem, true);
    }

    /**
     * for循环
     *
     * @param beanList
     * @param onForItem 根据结果是否继续循环
     * @param asc       是否正序查找
     * @param <T>
     */
    public static <T> void forEarch(List<T> beanList, OnForItem<T> onForItem, boolean asc) {
        if (Obj.isNULL(beanList)) return;
        if (asc) {
            for (int i = 0; i < beanList.size(); i++) {
                if (onForItem.onItem(beanList.get(i), i)) break;
            }
        } else {
            for (int i = beanList.size() - 1; i > -1; i--) {
                if (onForItem.onItem(beanList.get(i), i)) break;
            }
        }

    }

    public interface OnForItem<T> {
        boolean onItem(T t, int position);
    }

    public interface OnserchResult<T> {
        boolean match(T s);

        void onResult(T result);
    }

    public interface OnRemoveResult<T> {
        boolean match(T s);

        void onRemove(T result);
    }


}
